package edu.hawaii.ics.pjdb.util;

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class JdbcHelper {
    /**
     * Gets a connection to an embedded instance of Apache Derby with the
     * database located at the specified path.
     * 
     * Default behavior is to create the database if it doesn't exist.
     * 
     * @param filename
     * @return
     */
    public static Connection getDerbyConnection(String filename) {
        try {
            // Check if the database exists. If it doesn't, append ;create=true
            // to
            // the URL.
            File db = new File(filename);
            boolean exists = false;

            // If the parent file's list is null, we need to make some
            // directories...
            if (!db.exists() && db.getParentFile().listFiles() == null) {
                db.mkdirs();
            } else if (!db.exists()) {
                // Check for files that have the same prefix in this directory
                for (File child : db.getParentFile().listFiles()) {
                    if (child.getName().startsWith(db.getName())) {
                        exists = true;
                    }
                }
            }

            System.setProperty("derby.stream.error.file", "error.txt");
            System.setProperty("derby.system.home", db.getParent());

            // Largest page size Derby allows. This will reduce the number of
            // I/O
            // operations and speed things up a bit.
            System.setProperty("derby.storage.pageSize", "32768");
            // Larger page cache will speed things up. TODO: determine this
            // dynamically
            // from Runtime.getRuntime().
            // 32KB page size / 10K cache size ~= 312MB of memory (not including
            // overhead).
            // System.setProperty("derby.storage.pageCacheSize", "10000");

            Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
            String url = String.format("jdbc:derby:%s", db.getAbsolutePath());

            if (!exists) {
                url = url.concat(";create=true");
            }

            return DriverManager.getConnection(url);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("Failed to load Derby db driver!", e);
        } catch (SQLException e) {
            throw new RuntimeException("Error connecting to derby database.", e);
        } catch (InstantiationException e) {
            throw new RuntimeException("Failed to load Derby db driver!", e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("Failed to load Derby db driver!", e);
        }
    }
}
